package controllers

import (
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"github.com/astaxie/beego"
	"hello/conf"
	"hello/lib"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"
)

type AirkissController struct {
	beego.Controller
	PublicController
}

type Ticket struct {
	ExpireTime int64 `json:"expire_time"`
	JsapiTicket string `json:"jsapi_ticket"`
}
type TicketResponse struct {
	Errcode int `json:"errcode"`
	Errmsg string `json:"errmsg"`
	Ticket string `json:"ticket"`
	ExpiresIn string `json:"expires_in"`
}
func (ac *AirkissController) Get() {
	// 获取完整url
	subUrl := ac.Ctx.Request.RequestURI
	schema := ""
	if ac.Ctx.Request.TLS == nil {
		schema = "http://"
	} else {
		schema = "https://"
	}
	url := schema + ac.Ctx.Request.Host + subUrl
	log.Printf("url is: %s",url)
	ac.TplName = "airkiss.html"
	timestamp := time.Now().Unix()
	noncestr := createNonceStr(16)
	ticket := getJsApiTicket()
	timestampstr := strconv.Itoa(int(timestamp))
	signature := generateSignature(ticket, noncestr, timestampstr, url)
	ac.Data["AppID"] = conf.AppId
	ac.Data["Timestamp"] = timestamp
	ac.Data["NonceStr"] = noncestr
	ac.Data["JsApiTicket"] = ticket
	ac.Data["Signature"] = signature
}
func generateSignature(ticket, nonceStr, timestamp, url string) string{
	str := "jsapi_ticket=JSAPI_TICKET&noncestr=NONCESTR&timestamp=TIMESTAMP&url=URL"
	// handle str
	str = strings.Replace(str, "JSAPI_TICKET", ticket, 1)
	str = strings.Replace(str, "NONCESTR", nonceStr, 1)
	str = strings.Replace(str, "TIMESTAMP", timestamp, 1)
	str = strings.Replace(str, "URL", url, 1)
	s := sha1.New()
	s.Write([]byte(str))
	return hex.EncodeToString(s.Sum(nil))
}

func getJsApiTicket() string {
	content, err := ioutil.ReadFile("static/jsapi_ticket.txt")
	if err != nil {
		log.Printf("read ticket file error :%s", err.Error())
	}
	var ticket Ticket
	err = json.Unmarshal(content, &ticket)
	if err != nil {
		log.Printf("unmarshal error :%s", err.Error())
	}
	if ticket.ExpireTime < time.Now().Unix() {
		t := AccquireTicket()
		return t.JsapiTicket
	} else {
		return ticket.JsapiTicket
	}

}

func AccquireTicket() Ticket {
	var ticket Ticket
	var ticketresponse TicketResponse
	//token, err := redisLib.Get(redisLib.DB0, redisLib.AccessToken)
	token := lib.GetAccessToken()
	url := strings.Replace(conf.JsApiTicketUrl, "ACCESS_TOKEN", token, 1)
	resp, err := http.Get(url)
	if err != nil {
		log.Printf("get jsapiticket error :%s", err.Error())
	}
	if resp != nil {
		data, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			log.Printf("read response body error :%s", err.Error())
		}
		err = json.Unmarshal(data, &ticketresponse)
		if err != nil {
			log.Printf("unmarshal ticket error :%s", err.Error())
		}
		ticket.JsapiTicket = ticketresponse.Ticket
		ticket.ExpireTime = 7000 + time.Now().Unix()
		ticketdata, err := json.Marshal(ticket)
		if err != nil {
			log.Printf("marshal ticket error :%s", err.Error())
		}
		err = ioutil.WriteFile("static/jsapi_ticket.txt", ticketdata, os.FileMode(os.O_WRONLY))
		if err != nil {
			log.Printf("write file error :%s", err.Error())
		}
	}
	return ticket
}

func createNonceStr(length int) string {
	chars := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
	str := make([]rune, length)
	for i:= range str {
		str[i] = chars[rand.Intn(62 - i)]
	}
	return string(str)
}





